package spring;


import java.util.concurrent.atomic.AtomicBoolean;

public abstract class AbstractApplicationContext implements ApplicationContext{

    protected BeanDefinitionRegistry register = new DefaultListableBeanFactory();

    private long startupDate;

    private final AtomicBoolean active = new AtomicBoolean();

    private final AtomicBoolean closed = new AtomicBoolean();

    final Object startShutdownMonitor = new Object();

    public void refresh() {

        synchronized (this.startShutdownMonitor) {

            prepareRefresh();

            DefaultListableBeanFactory beanFactory = (DefaultListableBeanFactory) register;

            // 进行工厂必要的一些参数设置
            prepareBeanFactory(beanFactory);

            try {

                // 标志位的设置
                postProcessBeanFactory(beanFactory);

                // Spring正常开发的时候，仅仅有ConfigurationClassPathBeanPostProcess被调用执行，即执行顶级注解的注册
                invokeBeanFactoryPostProcessors(beanFactory);

                // BeanPostProcessor的注册
                registerBeanPostProcessors(beanFactory);

                // 有关国际化的操作，这里空实现
                initMessageSource();

                // Initialize event multicaster for this context.
                // 事件操作，后续在SpringCloud中会涉及到事件,这里空实现
                initApplicationEventMulticaster();

                // Initialize other special beans in specific context subclasses.
                // web中的ApplicationContext会使用到，在非web环境很少使用 ===> 空壳
                onRefresh();

                // Check for listener beans and register them.
                // 注册监听器，也是与Spring事件模型相关的内容，这里空实现
                registerListeners();

                /*
                 * 核心目的：通过Spring的beanFactory创建单例(非延迟)对象
                 * 1、注册BeanDefinition 2、准备BeanPostProcessor
                 * */
                finishBeanFactoryInitialization(beanFactory);

                // Last step: publish corresponding event.
                // 发布监听事件
                finishRefresh();


            } catch (Exception e) {
                e.printStackTrace();
            }


        }


    }

    protected void finishBeanFactoryInitialization(DefaultListableBeanFactory beanFactory) {
        // 注册非懒加载的对象
        beanFactory.preInstantiateSingletons();
    }

    /**
     * 进行BeanFactoryPostProcessors的调用处理
     *
     * @param beanFactory
     */
    protected void invokeBeanFactoryPostProcessors(DefaultListableBeanFactory beanFactory) {
        PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(beanFactory);
    }

    protected void postProcessBeanFactory(DefaultListableBeanFactory beanFactory) {
        // 允许在上下文子类中对bean工厂进行后处理。
    }

    protected void prepareRefresh() {
        this.startupDate = System.currentTimeMillis();
        this.active.set(true);
        this.closed.set(false);
    }

    protected BeanDefinitionRegistry obtainFreshBeanFactory() {
        refreshBeanFactory();
        return getBeanFactory();
    }

    private void refreshBeanFactory() {
        // 暂时未提供实现
    }

    private BeanDefinitionRegistry getBeanFactory() {
        return this.register;
    }

    protected void prepareBeanFactory(DefaultListableBeanFactory beanFactory) {
        beanFactory.setLoader(AbstractApplicationContext.class.getClassLoader());
    }

    public <T> T getBean(String name, Class<T> requiredType) {
        return ((DefaultListableBeanFactory) register).getBean(name, requiredType);
    }

    @Override
    public Object getBean(String name) {
        return ((DefaultListableBeanFactory) register).getBean(name);
    }

    protected void finishRefresh() {
    }

    protected void registerListeners() {
    }

    protected void onRefresh() {
    }

    protected void initApplicationEventMulticaster() {
    }

    protected void initMessageSource() {
    }

    protected void registerBeanPostProcessors(DefaultListableBeanFactory beanFactory) {
        PostProcessorRegistrationDelegate.registerBeanPostProcessors(beanFactory);
    }


}
